#include <iostream>
#include <vector>
#include <cstdlib>

using namespace std;

class zespolona{
	public: float a;
	public: float b;

	public: zespolona(float a, float b){
		this->a = a;
		this->b = b;
	}

	public: void zmien(float a, float b){
		this->a = a;
		this->b = b;
	}

	public: void wypisz(){
		if( a >= 0 )
			cout << a;
			else
			cout << "(" << a << ")";

		if( b >= 0 )
			cout << "+" << b << "i";
			else
			cout << "+(" << b << "i)";

		cout << "\n";
	}
};

class dzialania{

	//korzystamy z konstruktura domyślenego
	/*
	public: dzialania(){
	}
	*/
	
	public: zespolona suma(zespolona a, zespolona b){
		return zespolona(a.a + b.a,a.b + b.b);	
	}
	
	public: zespolona roznica(zespolona a, zespolona b){
		return zespolona(a.a - b.a,a.b - b.b);	
	}

	public: zespolona iloczyn(zespolona a, zespolona b){
		return zespolona((a.a*b.b)-(a.b*b.a),(a.a*b.b)+(a.b*b.a));
	}
	
	public: zespolona iloraz(zespolona a, zespolona b){
		return zespolona((a.a*b.a-a.b*(-b.b))/(b.a*b.a+b.b*b.b),(a.a*(-b.b)+a.b*b.a)/(b.a*b.a+b.b*b.b)); 
	}
	
	public: zespolona sprzezenie(zespolona a){
		return zespolona(a.a,-a.b);
	}
	
	public: float Re(zespolona a){
		return a.a;
	}
	
	public: float Im(zespolona a){
		return a.b;
	}
	
	public: zespolona potegowanie(zespolona a, int n){
		if( n == 0 ) return zespolona(0,0);
		if( n == 1 ) return a;
		for(int i =1; i < n; i++){
			a = iloczyn(a,a);
		}
		return a;
	}
};

void lista(){
	cout 	<< "________________________________________________________________________\n"
			<< "Co chcesz zrobić?\n"
			<< "i : inicjuj zespoloną\n" 
			<< "s : dodawanie | "
			<< "m : odejmowanie | "
			<< "a : mnożenie  | "
			<< "d : dzielenie\n"
			<< "r : część Re | "
			<< "u : część Im | "
			<< "z : sprzężenie | "
			<< "w : wyswietl | "
			<< "l : lista\n"
			<< "b : o programie | "
			<< "q : WYJŚCIE\n"
			<< "________________________________________________________________________\n" << endl;
}


void about(){
	cout 	<< "Autor : Rafał Gawlik \tra.gawlik@gmail.com\n"
			<< "Implementacja świata liczb zespolonych.\n"
			<< "________________________________________________________________________\n" << endl;
}

int main(){
	system("clear");
	vector <zespolona> A;
	dzialania operacje;
	
	zespolona a(0,0);
	
	int m,l;
	char znak, w;
	
	lista();
	while(true){
		cout 	<<"o - lista operacji\t"
				<<"c - czyszczenie ekranu\n"
				<<"Podaj znak operacji:";
		
		cin >> znak;
		
		switch(znak){
		
			case 'o':
						POWROT:
						system("clear");
						lista();
						break;
			
			case 'c':
						system("clear");
						break;
			
			case 'b':
						system("clear");
						about();
						break;
			
			case 'i':	//inicjacja liczby zespolonej
						system("clear");
						cout <<"INICJACJA LICZBY ZESPOLONEJ"<< endl;
						float r,u;
						cout << "Re:";
						cin >> r;
						cout << "Im:";
						cin >> u; 
						a.zmien(r,u);
						A.push_back(a);
						system("clear");
						A[A.size()-1].wypisz();
						cout << "Sukces: dopisano liczbę zespoloną do końca wektora!" << endl;
						break;
			
			case 's':	//suma dwóch zainicjowanych zespoloych
						system("clear");
						cout <<"SUMA"<< endl;
						cout << "Podaj indeksy liczb zespolonych do sumowania:" << endl;
						cout << "Pierwszy: ";
						cin >> m;
						cout << "Drugi: ";
						cin >> l;
						a = operacje.suma(A[m],A[l]);
						system("clear");
						a.wypisz();
						A.push_back(a);
						cout << "Sukces: zsumowano liczby i dodano wynik do końca wektora!" << endl;
						break;
						
			case 'm':	//różnica dwóch zainicjowanych zespoloych
						system("clear");
						cout << "RÓŻNICA"<< endl;
						cout << "Podaj indeksy liczb zespolonych do odejmowania:" << endl;
						cout << "Pierwszy: ";
						cin >> m;
						cout << "Drugi: ";
						cin >> l;
						a = operacje.roznica(A[m],A[l]);
						system("clear");
						a.wypisz();
						A.push_back(a);
						cout << "Sukces: wyliczono różnicę liczb i dodano wynik do końca wektora!" << endl;
						break;
			
			case 'a':	//iloczyn dwóch zainicjowanych zespoloych
						system("clear");
						cout << "ILOCZYN"<< endl;
						cout << "Podaj indeksy liczb zespolonych do mnożenia:" << endl;
						cout << "Pierwszy: ";
						cin >> m;
						cout << "Drugi: ";
						cin >> l;
						a = operacje.iloczyn(A[m],A[l]);
						system("clear");
						a.wypisz();
						A.push_back(a);
						cout << "Sukces: wymnożono liczby i dodano wynik do końca wektora!" << endl;
						break;
			
			case 'd':	//iloraz dwóch zainicjowanych zespoloych
						system("clear");
						cout << "ILORAZ"<< endl;
						cout << "Podaj indeksy liczb zespolonych do dzielenia:" << endl;
						cout << "Pierwszy: ";
						cin >> m;
						cout << "Drugi: ";
						cin >> l;
						a = operacje.iloraz(A[m],A[l]);
						system("clear");
						a.wypisz();
						A.push_back(a);
						cout << "Sukces: dokonano ilorazu liczb i dodano wynik do końca wektora!" << endl;
						break;			
			
			case 'r':	//część rzeczywista
						system("clear");
						cout << "CZĘŚĆ RZECZYWISTA"<< endl;
						cout << "Podaj indeks liczby zespolonej do wy-ścia części rzeczywistej:" << endl;
						cin >> m;
						system("clear");
						cout << "Re: " << operacje.Re(A[m]) << endl;
						break;
			
			case 'u':	//część urojona
						system("clear");
						cout << "CZĘŚĆ UROJONA"<< endl;
						cout << "Podaj indeks liczby zespolonej do wyświetlenia części urojonej:" << endl;
						cin >> m;
						system("clear");
						cout << "Im: " << operacje.Re(A[m]) << endl;
						break;
			
			case 'z':	//sprzęzenie liczby
						system("clear");
						cout << "SPRZĘŻENIE"<< endl;
						cout << "Podaj indeks liczby zespolonej do sprzężenia:" << endl;
						cin >> m;
						a = operacje.sprzezenie(A[m]);
						system("clear");
						a.wypisz();
						A.push_back(a);
						cout << "Sukces: sprzężono liczbę, liczbę sprzężoną dodano do końca wektora!" <<endl;
						break;
			
			case 'w':
						system("clear");
						cout << "WYŚWIETLENIE"<< endl;
						cout <<"podaj indeks liczby do wyświetlenia" << endl;
						cin >> m;
						system("clear");
						A[m].wypisz();
						break;
			
			case 'l':	//lista zainicjowanych zespolonych
						system("clear");
						cout << "LISTA"<< endl;
						if(A.size() == 0)
							cout << "Lista jest pusta" <<endl;
						else
							for(int i = A.size()-1; i>=0; i--){
								cout << "["<< i <<"] \t"; 
								A[i].wypisz();	
							}
						break;
						
			case 'q':
						system("clear");
						cout << "WYJŚCIE"<< endl;
						cout << "Czy na pewno chcesz wyjść? (t/n): ";
						cin >> w;
						if ( w=='t' )
							goto WYJSCIE;
							else
							goto POWROT;
						break;
			
			default:	
						system("clear");
						cout << "Co? Nie rozumiem tego co napisałeś!"<<endl;
						break;
		}
		
	}
	
	//przeskok z q
	WYJSCIE: cout << "Narazie! Wróć tu jeszcze. ;)"<< endl;	

}